package cqrtplm.vo.query;

import org.apache.ibatis.jdbc.SQL;
import java.util.List;
public class AdvancedQueryBuilder {

    public static String buildQuerySQL(AdvancedQueryConfig config, List<AdvancedQueryConditionVO> conditions) {
        if (!AdvancedQueryValidator.isValidTableName(config.getMainTable())) {
            throw new SecurityException("主表名格式不合法: " + config.getMainTable());
        }

        if (!validateConditions(conditions)) {
            throw new SecurityException("查询条件安全验证失败");
        }

        SQL sql = new SQL();
        buildSelectPart(sql, config);
        buildFromPart(sql, config);
        buildWherePart(sql, config, conditions);
        buildOrderByPart(sql, conditions);

        String generatedSQL = sql.toString();

        if (AdvancedQueryValidator.containsSqlInjection(generatedSQL)) {
            throw new SecurityException("生成的SQL包含潜在的安全风险");
        }

        return generatedSQL;
    }

    public static String buildPagedQuerySQL(AdvancedQueryConfig config, List<AdvancedQueryConditionVO> conditions) {
        String baseSQL = buildQuerySQL(config, conditions);

        AdvancedQueryConditionVO pageCondition = getPageCondition(conditions);
        if (pageCondition != null) {
            int start = (pageCondition.getPageNum() - 1) * pageCondition.getPageSize();
            int end = pageCondition.getPageNum() * pageCondition.getPageSize();

            return "SELECT * FROM (" +
                    "SELECT rownum rn, t.* FROM (" + baseSQL + ") t " +
                    "WHERE rownum <= " + end +
                    ") WHERE rn > " + start;
        }

        return baseSQL;
    }

    private static boolean validateConditions(List<AdvancedQueryConditionVO> conditions) {
        if (conditions == null) return true;

        for (AdvancedQueryConditionVO condition : conditions) {
            if (!condition.validate()) {
                //logger.warn("条件验证失败: {}", condition.getValidationError());
                return false;
            }
        }

        return true;
    }

    private static void buildSelectPart(SQL sql, AdvancedQueryConfig config) {
        sql.SELECT("*");
    }

    private static void buildFromPart(SQL sql, AdvancedQueryConfig config) {
        sql.FROM(config.getMainTable());
    }

    private static void buildWherePart(SQL sql, AdvancedQueryConfig config, List<AdvancedQueryConditionVO> conditions) {
        if (conditions == null || conditions.isEmpty()) return;

        for (AdvancedQueryConditionVO condition : conditions) {
            String dbField = getFieldName(config, condition);
            String operator = condition.getOperator();

            switch (operator.toUpperCase()) {
                case "IS NULL":
                    sql.WHERE(dbField + " IS NULL");
                    break;
                case "IS NOT NULL":
                    sql.WHERE(dbField + " IS NOT NULL");
                    break;
                case "IN":
                    sql.WHERE(dbField + " IN (" + buildInClause(condition.getValue()) + ")");
                    break;
                case "NOT IN":
                    sql.WHERE(dbField + " NOT IN (" + buildInClause(condition.getValue()) + ")");
                    break;
                case "BETWEEN":
                    sql.WHERE(dbField + " BETWEEN ? AND ?");
                    break;
                case "LIKE":
                    sql.WHERE(dbField + " LIKE CONCAT('%', ?, '%')");
                    break;
                case "NOT LIKE":
                    sql.WHERE(dbField + " NOT LIKE CONCAT('%', ?, '%')");
                    break;
                default:
                    sql.WHERE(dbField + " " + operator + " ?");
                    break;
            }
        }
    }

    private static void buildOrderByPart(SQL sql, List<AdvancedQueryConditionVO> conditions) {
        if (conditions != null) {
            conditions.stream()
                    .filter(c -> c.getSortConditions() != null)
                    .flatMap(c -> c.getSortConditions().stream())
                    .forEach(sc -> sql.ORDER_BY(sc.getField() + " " + sc.getDirection()));
        }
    }

    private static String getFieldName(AdvancedQueryConfig config, AdvancedQueryConditionVO condition) {
        String dbField = config.getDbField(condition.getField());

        if (!AdvancedQueryValidator.isValidFieldName(dbField)) {
            throw new SecurityException("数据库字段名不合法: " + dbField);
        }

        if (condition.getTableAlias() != null) {
            if (!AdvancedQueryValidator.isValidTableAlias(condition.getTableAlias())) {
                throw new SecurityException("表别名不合法: " + condition.getTableAlias());
            }
            return condition.getTableAlias() + "." + dbField;
        }

        return dbField;
    }

    private static String buildInClause(Object value) {
        if (value instanceof List) {
            List<?> list = (List<?>) value;
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < list.size(); i++) {
                if (i > 0) sb.append(",");
                sb.append("?");
            }
            return sb.toString();
        }
        return "?";
    }

    private static AdvancedQueryConditionVO getPageCondition(List<AdvancedQueryConditionVO> conditions) {
        if (conditions != null) {
            for (AdvancedQueryConditionVO condition : conditions) {
                if (condition.getPageNum() != null && condition.getPageSize() != null) {
                    return condition;
                }
            }
        }
        return null;
    }
}
